#===============================================================================
# Copyright 2004-2017 Intel Corporation All Rights Reserved.
#
# The source code,  information  and material  ("Material") contained  herein is
# owned by Intel Corporation or its  suppliers or licensors,  and  title to such
# Material remains with Intel  Corporation or its  suppliers or  licensors.  The
# Material  contains  proprietary  information  of  Intel or  its suppliers  and
# licensors.  The Material is protected by  worldwide copyright  laws and treaty
# provisions.  No part  of  the  Material   may  be  used,  copied,  reproduced,
# modified, published,  uploaded, posted, transmitted,  distributed or disclosed
# in any way without Intel's prior express written permission.  No license under
# any patent,  copyright or other  intellectual property rights  in the Material
# is granted to  or  conferred  upon  you,  either   expressly,  by implication,
# inducement,  estoppel  or  otherwise.  Any  license   under such  intellectual
# property rights must be express and approved by Intel in writing.
#
# Unless otherwise agreed by Intel in writing,  you may not remove or alter this
# notice or  any  other  notice   embedded  in  Materials  by  Intel  or Intel's
# suppliers or licensors in any way.
#===============================================================================

##  Content:
##     Intel(R) Math Kernel Library Sparse BLAS Fortran examples makefile
##******************************************************************************

# include spblasf.lst

define usage

Usage:
------
  #> make Target                          \
          [interface=interface_name]      \
          [threading=parallel|sequential] \
          [MKLROOT=path]                  \
          [example=name]

  Targets:

    libia32      - statically linked example for processors that use the IA-32 architecture"
    dylibia32    - dynamically linked example for processors that use the IA-32 architecture"
    libintel64   - statically linked example for processors that use the Intel(R) 64 architecture"
    dylibintel64 - dynamically linked example for processors that use the Intel(R) 64 architecture"
    help         - print this help"

  Options:

    interface=interface_name
                - Can be lp64 (default) or ilp64 for intel64.

    threading=parallel
        - Use Intel(R) MKL in the threaded mode, default.
    threading=sequential
        - Use Intel(R) MKL in the sequential mode

    MKLROOT=<MKL_directory>
        - Specifies the location of Intel(R) MKL libraries used to build this example.
          Default: the Intel(R) MKL installation directory.

    example="example1 example2 ..."
        - Specifies the list of examples to run (source name without extension).
          Proper values are:
          $(SPBLAS)
          All examples will be executed by default.

Usage examples:
--------------
  #> make libia32 example="solver_cg"
        -  Link 'solver_cg' example against parallel static MKL-IA32.

  #> make dylibintel64 interface=ilp64 threading=sequential
        - Link all the examples against sequential dynamic MKL-Intel64
          using ILP64 interface.

endef

help: export usage := $(usage)
help: ; @echo "$$usage"

# Main targets
libintel64:   ; $(MAKE) ext=a  _ia=intel64 run
dylibintel64: ; make -f macos.mak ext=so _ia=intel64 run
rtintel64:    ; $(MAKE) ext=rt _ia=intel64 run
libia32:      ; $(MAKE) ext=a  _ia=ia32    run
dylibia32:    ; $(MAKE) ext=so _ia=ia32    run
rtia32:       ; $(MAKE) ext=rt _ia=ia32    run

# Check options and set default values
#   call args: $1 - option name, $2 - default value, $3 - other appropriate values for the option
check-opt = \
    $(if $(value $(strip $1)),,$(eval override $1 = $2)) \
    $(if $(filter $2 $3, $(value $(strip $1))),, \
        $(error [ERROR] Incorrect option value: '$(strip $1)=$(value $(strip $1))'! Should be some of '$(strip $2 $3)'))
$(call check-opt, threading, parallel, sequential)
# $(call check-opt, example, $(SPBLAS))
$(call check-opt, interface, lp64, ilp64)
$(call check-opt, MKLROOT, /opt/intel/mkl, %)
compiler=intel

# Paths to Intel(R) MKL libraries
IMKL_PATH  = "$(MKLROOT)/lib"
IOMP_PATH  = "$(MKLROOT)/../compiler/lib"

# Vendor specific compiler options
FOPTS.intel = $(if $(iface.ilp64),-i8) -warn all -module $(RES_DIR) -fpp
FOPTS.intel.ia32 = -m32    # This option tells compiler to generate code for IA-32 architecture.
FOPTS.intel.intel64 = -m64 # This option tells compiler to generate code for Intel64 architecture.

# This definition is needed for the example itself on IA-32 architecture
FOPTS.ia32 = -D_IA32
# Used to debugger
DEBUGGER = -g
FOPTS = $(FOPTS.$(compiler).$(_ia)) $(FOPTS.$(compiler)) $(FOPTS.$(_ia)) $(DEBUGGER)

# Macro to use in conditions
iface.$(interface) = $(interface)
platform.$(_ia) = $(_ia)

# Linker options
LINK_OPTS = $(IMKL_LIBS.$(ext)) -L $(IOMP_PATH) -liomp5 -lm

# Intel(R) MKL libraries to use in linking
IMKL_LIBS    = $(iface_lib.$(compiler))$(suffix_lib.$(_ia)) mkl_core mkl_$(compiler)_thread




# added bymyseft
LIB95=$(MKLROOT)/lib/libmkl_blas95_$(interface).a
EXT = dylib
IFACE_COMP_PART=intel
IFACE_LIB=$(MKLROOT)/lib/libmkl_$(IFACE_COMP_PART).$(EXT)
IFACE_THREADING_PART=intel
THREADING_LIB=$(MKLROOT)/lib/libmkl_$(IFACE_THREADING_PART)_thread.$(EXT)
CORE_LIB=$(MKLROOT)/lib/libmkl_core.$(EXT)
MKL_LIBS=$(IFACELIB) $(THREADING_LIB) $(CORE_LIB)
MODPATH=$(MKLROOT)/include/intel64/$(interface)



IMKL_LIBS.a  = $(IMKL_LIBS:%=$(IMKL_PATH)/lib%.a)
IMKL_LIBS.so = -L $(IMKL_PATH) $(IMKL_LIBS:%=-l%)
IMKL_LIBS.rt = -L $(IMKL_PATH) -lmkl_rt

iface_lib.$(compiler) = mkl_intel
suffix_lib.$(_ia)     = _$(interface)
suffix_lib.ia32       =

# Compiler tools
RPATH = -Wl,-rpath,$(IMKL_PATH) -Wl,-rpath,$(IOMP_PATH)
FC.intel = ifort




FC.comp = $(FC.$(compiler)) $(FOPTS) $(RPATH) -I$(MODPATH) -I$(MKLROOT)/include -w $(FOPTS.f.$(compiler))

#-------------------------------------------------------------------------------

RES_DIR = .
RES = $(example:%=$(RES_DIR)/%.res)
SOU_DIR = .


run   : $(RES)
$(RES): .FORCE
.FORCE:
.PHONY: run

$(RES_DIR)/%.res: $(RES_DIR)/%.exe ; $(shell which env) $< > $@

MODULE_PARDISO = $(RES_DIR)/mkl_pardiso.o

.SECONDARY:
$(RES_DIR)/%.exe: $(RES_DIR)/%.o $(MODULE_PARDISO) common_functions.o sparseoperator.o; $(FC.comp) $^ -o $@ $(LINK_OPTS)

$(RES_DIR)/%.o: $(SOU_DIR)/%.f90 common_functions.o sparseoperator.o | $(RES_DIR)/. ;	$(FC.comp) $< -c -o $@

$(RES_DIR)/%.o: $(SOU_DIR)/%.f | $(RES_DIR)/. ; $(FC.comp) $< -c -o $@

common_functions.o: common_functions.f90 | $(RES_DIR)/. ; $(FC.comp) $< -c -o $@

sparseoperator.o: sparseoperator.f90 common_functions.o $(MODULE_PARDISO) | $(RES_DIR)/. ; $(FC.comp) $< -c -o $@

$(MODULE_PARDISO): $(MKLROOT)/include/mkl_pardiso.f90 | $(RES_DIR)/. ; $(FC.comp) $< -c -o $@

%/. : ; mkdir -p $@
